<!DOCTYPE html>
<html lang="">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noodp" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
        <title>向spring提交了一个issue - 暗夜零星</title><meta name="Description" content="暗夜零星，java程序员。这里是我的个人博客，交流技术，分享经验。"><meta property="og:title" content="向spring提交了一个issue" />
<meta property="og:description" content="昨天给spring提了一个issue，这个问题在 声明式事务注意事项 中有描述过。" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://wlizhi.cc/posts/spring/an-issue-for-spring/" /><meta property="og:image" content="https://wlizhi.cc/logo.png"/><meta property="article:section" content="posts" />
<meta property="article:published_time" content="2020-12-11T12:47:01+08:00" />
<meta property="article:modified_time" content="2020-12-11T12:47:01+08:00" />

<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:image" content="https://wlizhi.cc/logo.png"/>

<meta name="twitter:title" content="向spring提交了一个issue"/>
<meta name="twitter:description" content="昨天给spring提了一个issue，这个问题在 声明式事务注意事项 中有描述过。"/>
<meta name="application-name" content="暗夜零星">
<meta name="apple-mobile-web-app-title" content="暗夜零星"><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="manifest" href="/site.webmanifest"><link rel="canonical" href="https://wlizhi.cc/posts/spring/an-issue-for-spring/" /><link rel="prev" href="https://wlizhi.cc/posts/spring/21-load-servlet-container-initializer-on-startup/" /><link rel="next" href="https://wlizhi.cc/posts/spring/22-enable-web-mvc-main-embedded-tomcat/" /><link rel="stylesheet" href="/lib/normalize/normalize.min.css"><link rel="stylesheet" href="/css/style.min.css"><link rel="stylesheet" href="/lib/fontawesome-free/all.min.css"><link rel="stylesheet" href="/lib/animate/animate.min.css"><script type="application/ld+json">
    {
        "@context": "http://schema.org",
        "@type": "BlogPosting",
        "headline": "向spring提交了一个issue",
        "inLanguage": "",
        "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": "https:\/\/wlizhi.cc\/posts\/spring\/an-issue-for-spring\/"
        },"genre": "posts","keywords": "spring源码, spring问题","wordcount":  2888 ,
        "url": "https:\/\/wlizhi.cc\/posts\/spring\/an-issue-for-spring\/","datePublished": "2020-12-11T12:47:01+08:00","dateModified": "2020-12-11T12:47:01+08:00","publisher": {
            "@type": "Organization",
            "name": "Wlizhi"},"author": {
                "@type": "Person",
                "name": "Wlizhi"
            },"description": ""
    }
    </script></head>
    <body header-desktop="fixed" header-mobile="auto"><script type="text/javascript">(window.localStorage && localStorage.getItem('theme') ? localStorage.getItem('theme') === 'dark' : ('auto' === 'auto' ? window.matchMedia('(prefers-color-scheme: dark)').matches : 'auto' === 'dark')) && document.body.setAttribute('theme', 'dark');</script>

        <div id="mask"></div><div class="wrapper"><header class="desktop" id="header-desktop">
    <div class="header-wrapper">
        <div class="header-title">
            <a href="/" title="暗夜零星"><span class="header-title-pre"><i class='far fa-moon fa-fw'></i></span>暗夜零星</a>
        </div>
        <div class="menu">
            <div class="menu-inner"><a class="menu-item" href="/posts/"> 所有文章 </a><a class="menu-item" href="/tags/"> 标签 </a><a class="menu-item" href="/categories/"> 分类 </a><a class="menu-item" href="/message-board/"> 留言 </a><a class="menu-item" href="/about/"> 关于 </a><a class="menu-item" href="https://github.com/wlizhi" title="GitHub" rel="noopener noreffer" target="_blank"><i class='fab fa-github fa-fw'></i>  </a><a class="menu-item" href="https://gitee.com/wlizhi" title="Gitee" rel="noopener noreffer" target="_blank"><i class='fab fa-git fa-fw'></i>  </a><span class="menu-item delimiter"></span><span class="menu-item search" id="search-desktop">
                        <input type="text" placeholder="点击搜索..." id="search-input-desktop">
                        <a href="javascript:void(0);" class="search-button search-toggle" id="search-toggle-desktop" title="搜索">
                            <i class="fas fa-search fa-fw"></i>
                        </a>
                        <a href="javascript:void(0);" class="search-button search-clear" id="search-clear-desktop" title="清空">
                            <i class="fas fa-times-circle fa-fw"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-desktop">
                            <i class="fas fa-spinner fa-fw fa-spin"></i>
                        </span>
                    </span><a href="javascript:void(0);" class="menu-item theme-switch" title="切换主题">
                    <i class="fas fa-adjust fa-fw"></i>
                </a>
            </div>
        </div>
    </div>
</header><header class="mobile" id="header-mobile">
    <div class="header-container">
        <div class="header-wrapper">
            <div class="header-title">
                <a href="/" title="暗夜零星"><span class="header-title-pre"><i class='far fa-moon fa-fw'></i></span>暗夜零星</a>
            </div>
            <div class="menu-toggle" id="menu-toggle-mobile">
                <span></span><span></span><span></span>
            </div>
        </div>
        <div class="menu" id="menu-mobile"><div class="search-wrapper">
                    <div class="search mobile" id="search-mobile">
                        <input type="text" placeholder="点击搜索..." id="search-input-mobile">
                        <a href="javascript:void(0);" class="search-button search-toggle" id="search-toggle-mobile" title="搜索">
                            <i class="fas fa-search fa-fw"></i>
                        </a>
                        <a href="javascript:void(0);" class="search-button search-clear" id="search-clear-mobile" title="清空">
                            <i class="fas fa-times-circle fa-fw"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-mobile">
                            <i class="fas fa-spinner fa-fw fa-spin"></i>
                        </span>
                    </div>
                    <a href="javascript:void(0);" class="search-cancel" id="search-cancel-mobile">
                        取消
                    </a>
                </div><a class="menu-item" href="/posts/" title="">所有文章</a><a class="menu-item" href="/tags/" title="">标签</a><a class="menu-item" href="/categories/" title="">分类</a><a class="menu-item" href="/message-board/" title="">留言</a><a class="menu-item" href="/about/" title="">关于</a><a class="menu-item" href="https://github.com/wlizhi" title="GitHub" rel="noopener noreffer" target="_blank"><i class='fab fa-github fa-fw'></i></a><a class="menu-item" href="https://gitee.com/wlizhi" title="Gitee" rel="noopener noreffer" target="_blank"><i class='fab fa-git fa-fw'></i></a><a href="javascript:void(0);" class="menu-item theme-switch" title="切换主题">
                <i class="fas fa-adjust fa-fw"></i>
            </a></div>
    </div>
</header>
<div class="search-dropdown desktop">
    <div id="search-dropdown-desktop"></div>
</div>
<div class="search-dropdown mobile">
    <div id="search-dropdown-mobile"></div>
</div>
<main class="main">
                <div class="container"><div class="toc" id="toc-auto">
            <h2 class="toc-title">目录</h2>
            <div class="toc-content" id="toc-content-auto"></div>
        </div><article class="page single"><h1 class="single-title animated flipInX">向spring提交了一个issue</h1><div class="post-meta">
            <div class="post-meta-line"><span class="post-author"><a href="https://wlizhi.cc" title="Author" target="_blank" rel="noopener noreffer author" class="author"><i class="fas fa-user-circle fa-fw"></i>Wlizhi</a></span>&nbsp;<span class="post-category">收录于 <a href="/categories/spring/"><i class="far fa-folder fa-fw"></i>spring</a></span></div>
            <div class="post-meta-line"><i class="far fa-calendar-alt fa-fw"></i>&nbsp;<time datetime="2020-12-11">2020-12-11</time>&nbsp;<i class="fas fa-pencil-alt fa-fw"></i>&nbsp;约 2888 字&nbsp;
                <i class="far fa-clock fa-fw"></i>&nbsp;预计阅读 6 分钟&nbsp;<span id="/posts/spring/an-issue-for-spring/" class="leancloud_visitors" data-flag-title="向spring提交了一个issue">
                        <i class="far fa-eye fa-fw"></i>&nbsp;<span class=leancloud-visitors-count></span>&nbsp;次阅读
                    </span>&nbsp;</div>
        </div><div class="details toc" id="toc-static"  kept="">
                <div class="details-summary toc-title">
                    <span>目录</span>
                    <span><i class="details-icon fas fa-angle-right"></i></span>
                </div>
                <div class="details-content toc-content" id="toc-content-static"><nav id="TableOfContents"></nav></div>
            </div><div class="content" id="content"><p>昨天给spring提了一个issue，这个问题在 <a href="https://wlizhi.cc/posts/spring/16-transaction-declare-attention/" target="_blank" rel="noopener noreffer">声明式事务注意事项</a> 中有描述过。</p>
<p>关于spring声明式事务传播行为 <code>REQUIRES_NEW</code>，如果不做额外处理，可能会导致所有数据库连接被占用的问题。一直搞不明白，这里隐藏着很大的问题，为什么要有这个传播行为。于是就将问题提交给了spring官方。</p>
<p><a href="https://github.com/spring-projects/spring-framework/issues/26250" target="_blank" rel="noopener noreffer">issue链接传送门</a></p>
<p>当多个线程争用资源时，每个线程必须在结束任务之前抢占多个资源，这可能是一个隐患。因为此方法可能导致多个线程仅抢夺它们需要的部分资源，它们无法获得所需要的所有资源而释放所获得的东西。但是，到这个时候，资源已经用尽了。</p>
<p>spring声明式事务中的传播行为 <code>REQUIRES_NEW</code> 正是以上情况的表现。</p>
<p>最终的沟通结果截图：</p>
<p><figure><a class="lightgallery" href="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-issue-from-github.png" title="沟通结果截图" data-thumbnail="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-issue-from-github.png" data-sub-html="<h2>spring-issue-from-github.png</h2><p>沟通结果截图</p>">
        <img
            class="lazyload"
            src="/svg/loading.min.svg"
            data-src="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-issue-from-github.png"
            data-srcset="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-issue-from-github.png, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-issue-from-github.png 1.5x, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-issue-from-github.png 2x"
            data-sizes="auto"
            alt="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-issue-from-github.png" />
    </a><figcaption class="image-caption">spring-issue-from-github.png</figcaption>
    </figure></p>
<p>详细的沟通过程：</p>
<p>最初提交的issue，我仅仅发了一段伪代码。内容如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">A method that opens a transaction calls another method that starts a new transaction，if all connections are exhausted before the last new transaction method is executed,then all threads in the process will block，this process will fail.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Pseudo code：
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">@Transactional
</span></span><span class="line"><span class="cl">methodA(){
</span></span><span class="line"><span class="cl">    // All the threads that started the transaction were executed here, but the connection was exhausted.
</span></span><span class="line"><span class="cl">    // The latter method execution will get a new connection,but it will never get it.
</span></span><span class="line"><span class="cl">    @Transactional(propagation=Propagation.REQUIRES_NEW)
</span></span><span class="line"><span class="cl">    methodB(){
</span></span><span class="line"><span class="cl">    }
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></td></tr></table>
</div>
</div><p>刚开始对方并没有认真的查看，仅回复<code>What's the problem?</code>。之后数次的回复貌似不在一个频道。也许是因为沟通时礼貌的原因、又或者是我问题描述的不够清楚。经过几次沟通后，差点把对方惹毛了，对方回复道：这里不是论坛，如果您认为是错误，请粘贴测试用例，如果您认为是改进，请提交PR，讨论到此为止。</p>
<p>以下是原文：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">It&#39;s not forum here, if you think it&#39;s a bug please paste test case, if you think it&#39;s an improvement please submit PR, end of discussion.
</span></span></code></pre></td></tr></table>
</div>
</div><p>看到对方不耐烦了，考虑到自己说话方式的问题，一番思虑后，决定再回复一下。回复内容尽可能将这个潜在问题描述清楚。
回复如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Sorry, I didn&#39;t make it clear. This is the test code, where it blocks the real process. Methodb() will never execute.
</span></span></code></pre></td></tr></table>
</div>
</div><p>百度翻译：抱歉，是我没有表达清楚。这是测试代码，它阻塞了整个进程。 methodB() 将永远不会执行。</p>
<p>示例代码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@slf4j</span>
</span></span><span class="line"><span class="cl"><span class="nd">@service</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PropagationExampleServiceImpl</span> <span class="kd">implements</span> <span class="n">PropagationExampleService</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl"><span class="nd">@Autowired</span>
</span></span><span class="line"><span class="cl"><span class="n">PropagationExampleService</span> <span class="n">service</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@Transactional</span>
</span></span><span class="line"><span class="cl"><span class="nd">@Override</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">methodA</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">InterruptedException</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">	<span class="n">Thread</span><span class="o">.</span><span class="na">sleep</span><span class="o">(</span><span class="n">100</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">	<span class="n">log</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">&#34;methodA&#34;</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">	<span class="n">service</span><span class="o">.</span><span class="na">methodB</span><span class="o">();</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@Transactional</span><span class="o">(</span><span class="n">propagation</span> <span class="o">=</span> <span class="n">Propagation</span><span class="o">.</span><span class="na">REQUIRES_NEW</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nd">@Override</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">methodB</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">InterruptedException</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">	<span class="n">log</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">&#34;methodB&#34;</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">	<span class="n">Thread</span><span class="o">.</span><span class="na">sleep</span><span class="o">(</span><span class="n">100</span><span class="o">);</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@SpringBootTest</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PropagationExampleServiceTest</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl"><span class="nd">@Autowired</span>
</span></span><span class="line"><span class="cl"><span class="n">PropagationExampleService</span> <span class="n">service</span><span class="o">;</span>
</span></span><span class="line"><span class="cl"><span class="n">ExecutorService</span> <span class="n">executor</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ThreadPoolExecutor</span><span class="o">(</span><span class="n">10</span><span class="o">,</span> <span class="n">10</span><span class="o">,</span> <span class="n">60</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="n">TimeUnit</span><span class="o">.</span><span class="na">SECONDS</span><span class="o">,</span> <span class="k">new</span> <span class="n">ArrayBlockingQueue</span><span class="o">&lt;&gt;(</span><span class="n">1000</span><span class="o">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@Test</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">methodATest</span><span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">20</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">		<span class="n">executor</span><span class="o">.</span><span class="na">execute</span><span class="o">(()</span> <span class="o">-&gt;</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">			<span class="k">try</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">				<span class="n">service</span><span class="o">.</span><span class="na">methodA</span><span class="o">();</span>
</span></span><span class="line"><span class="cl">			<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">InterruptedException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">				<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
</span></span><span class="line"><span class="cl">			<span class="o">}</span>
</span></span><span class="line"><span class="cl">		<span class="o">});</span>
</span></span><span class="line"><span class="cl">	<span class="o">}</span>
</span></span><span class="line"><span class="cl">	<span class="n">LockSupport</span><span class="o">.</span><span class="na">park</span><span class="o">();</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>连接池配置及日志：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">spring:
</span></span><span class="line"><span class="cl">datasource:
</span></span><span class="line"><span class="cl">name: druidDataSource
</span></span><span class="line"><span class="cl">type: com.alibaba.druid.pool.DruidDataSource
</span></span><span class="line"><span class="cl">druid:
</span></span><span class="line"><span class="cl">max-active: 10
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Here is the log:
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-1] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-2] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-5] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-6] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-8] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-9] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-3] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [ool-1-thread-10] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-7] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span><span class="line"><span class="cl">2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-4] c.j.s.s.i.PropagationExampleServiceImpl : methodA
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<p>好吧，对方以为是我使用过程遇到了问题，在像他求助，回复道：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">I think the result is expected, you should increase max-active &gt; concurrency, so If you change max-active to 21, it will pass, waiting for your confirmation.
</span></span><span class="line"><span class="cl">You should set a max-wait on dataSource, then getConnection will timeout instead of endless blocking.
</span></span></code></pre></td></tr></table>
</div>
</div><p>百度翻译：我认为结果是预期的，您应该增加 max-active 并发性，因此，如果将max-active更改为21，它将通过，等待确认。您应该在dataSource上设置一个max-wait，然后getConnection将超时而不是无限阻塞。</p>
<hr>
<p>以下是我的回复：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">I know, I just want to express that. In fact, the number of connections in the connection pool is generally not large. In the above example, only one layer is nested. If there are multiple layers of newly started transactions in the code, only a small amount of concurrency is needed to trigger the above result.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">I just think that when multiple threads compete for resources, each thread must grab multiple resources before ending the task, which may be a hidden danger.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Because this method may cause multiple threads to rob only a part of the resources they need. They can&#39;t release what they have acquired without getting all the resources they need. By this time, however, resources have been exhausted.
</span></span></code></pre></td></tr></table>
</div>
</div><p>百度翻译：我知道，我只想表达这一点。实际上，连接池中的连接数通常不大。在上面的示例中，仅嵌套了一层。如果代码中有多层新启动的事务，则只需少量的并发即可触发上述结果。我只是认为，当多个线程争用资源时，每个线程必须在结束任务之前抢占多个资源，这可能是一个隐患。因为此方法可能导致多个线程仅抢夺它们需要的部分资源。他们无法获得所需要的所有资源而释放所获得的东西。但是，到这个时候，资源已经用尽了。</p>
<hr>
<p>对方回复：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Your test blocked because you didn&#39;t set timeout for ds.getConnection(), for example maxWait for druid and connectionTimeout for HikariCP.
</span></span><span class="line"><span class="cl">It&#39;s really nothing to do with spring transaction.
</span></span></code></pre></td></tr></table>
</div>
</div><p>百度翻译：由于未为ds.getConnection（）设置超时（例如，为druid设置了maxWait，为HikariCP设置了connectionTimeout），因此测试被阻止。确实与spring transaction无关。</p>
<p>对方的回复让我觉得有点甩锅的意思。😢</p>
<p>最终决定，把我的意图整体发过去，然后就不再纠结了。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">I&#39;m sorry to have taken you so long.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">I just want to put forward what I think may be hidden dangers. It&#39;s not that I have encountered problems in use. I just don&#39;t quite understand why this place is designed in this way.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Even if Max wait is set here, the above situation may occur. It&#39;s just going to wait for a while, not the whole process, but it&#39;s bad enough.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">For this reason, I choose to avoid using REQUIRES_NEW, if I need to start a new transaction in a method, I will use asynchronous or transactionSynchronization.afterCommit ()。
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">You may say that the outer method will not be able to sense the exception, but why should it? These are two transactions. If I need the outer layer to sense the inner layer&#39;s anomaly, I can use NESTED.
</span></span></code></pre></td></tr></table>
</div>
</div><p>百度翻译：
很抱歉耽误你这么久。</p>
<p>我只想提出我认为可能存在的隐患。并不是说我在使用中遇到了问题。我只是不太明白为什么这个地方是这样设计的。</p>
<p>即使在这里设置了Max wait，也可能发生上述情况。只是要等一段时间，而不是整个进程挂掉，但这也足够糟糕了。</p>
<p>因此，我会选择尽可能避免使用REQUIRES_NEW，如果我必须在一个方法中启动一个新事务，我将使用asynchronous或transaActionSynchronization.afterCommit()将两个事务提交隔离。</p>
<p>您可能会说，外部方法将无法感知异常。但为什么要这样做呢？这本就是两个事务。如果我需要外层来感知内层的异常，我可以使用NESTED。</p>
<hr>
<p>最终对方给了一个我意想不到的回复：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">I admit your title &#34;Propagation.REQUIRES_NEW May cause all connections to be occupied&#34;.
</span></span><span class="line"><span class="cl">application should deal REQUIRES_NEW properly, there is no bug or improve space here, at most adding note in docs. Do you agree?
</span></span></code></pre></td></tr></table>
</div>
</div><p>百度翻译：我承认您的标题“ Propagation.REQUIRES_NEW可能导致所有连接被占用”。应用程序应该正确处理REQUIRES_NEW，此处没有错误或没有优化空间，最多只能在文档中添加注释。你同意吗？</p>
<hr>
<p>如果项目中有事务的传播行为设置为 <code>REQUIRES_NEW</code>，一定要仔细思考当前这个节点，是否真的需要新启事务，或者如果打乱外围方法和它之间的执行顺序，是否会有所影响？考虑这些问题的目的就是为了，尽可能避免这种传播行为的使用。如果真的避不开，就做异步处理或者使用事务同步器，进行后置处理。</p>
<p>如果这种方式还是会打乱原有业务，必须得使用 <code>REQUIRES_NEW</code>，也不允许做其他处理（我实在想不到这种场景），那最好对其进行限流。理论上进程中所有新启事务的方法个数要小于连接池连接数。允许的最大并发量要小于连接池连接数除以这种方法的个数，当然这是下下策。最终这些方法会以极慢的速度进行，甚至还不如直接塞到一个事务中。能拆分成两个事务解决的问题，使用一个事务一定也是可以解决的。</p>
<p>我个人认为 <code>REQUIRES_NEW</code> 这种传播行为机制是有一定问题的，至少这个问题在上面代码案例中已经表现出来了，而且触发的几率极高。替代这种传播行为的手段很多，何必要直接使用这种传播行为，埋下一个项目随时可能宕机（如果设置了超时，前文中说的结果被触发时，会一直卡顿到连接超时，事务回滚。）的隐患呢？</p>
<p>之所以没有直接发 issue 截图，是因为文章使用md文档写的，提交到其他博客网站时，图片链接可能会无法加载。所以以文字的形式先复制下来。后面再附上部分截图。</p>
<p>github部分沟通时的截图</p>
<p><figure><a class="lightgallery" href="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-01.png" title="spring-github-issue-transaction-01" data-thumbnail="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-01.png" data-sub-html="<h2>spring-github-issue-transaction-01</h2><p>spring-github-issue-transaction-01</p>">
        <img
            class="lazyload"
            src="/svg/loading.min.svg"
            data-src="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-01.png"
            data-srcset="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-01.png, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-01.png 1.5x, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-01.png 2x"
            data-sizes="auto"
            alt="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-01.png" />
    </a><figcaption class="image-caption">spring-github-issue-transaction-01</figcaption>
    </figure></p>
<p><figure><a class="lightgallery" href="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-02.png" title="spring-github-issue-transaction-02" data-thumbnail="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-02.png" data-sub-html="<h2>spring-github-issue-transaction-02</h2><p>spring-github-issue-transaction-02</p>">
        <img
            class="lazyload"
            src="/svg/loading.min.svg"
            data-src="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-02.png"
            data-srcset="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-02.png, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-02.png 1.5x, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-02.png 2x"
            data-sizes="auto"
            alt="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-02.png" />
    </a><figcaption class="image-caption">spring-github-issue-transaction-02</figcaption>
    </figure></p>
<p><figure><a class="lightgallery" href="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-03.png" title="spring-github-issue-transaction-03" data-thumbnail="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-03.png" data-sub-html="<h2>spring-github-issue-transaction-03</h2><p>spring-github-issue-transaction-03</p>">
        <img
            class="lazyload"
            src="/svg/loading.min.svg"
            data-src="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-03.png"
            data-srcset="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-03.png, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-03.png 1.5x, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-03.png 2x"
            data-sizes="auto"
            alt="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-03.png" />
    </a><figcaption class="image-caption">spring-github-issue-transaction-03</figcaption>
    </figure></p>
<p><figure><a class="lightgallery" href="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-04.png" title="spring-github-issue-transaction-04" data-thumbnail="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-04.png" data-sub-html="<h2>spring-github-issue-transaction-04</h2><p>spring-github-issue-transaction-04</p>">
        <img
            class="lazyload"
            src="/svg/loading.min.svg"
            data-src="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-04.png"
            data-srcset="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-04.png, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-04.png 1.5x, https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-04.png 2x"
            data-sizes="auto"
            alt="https://oss.wlizhi.cc/blog/spring/spring-github-transaction-propagation-issue/spring-github-issue-transaction-04.png" />
    </a><figcaption class="image-caption">spring-github-issue-transaction-04</figcaption>
    </figure></p></div>

        <div id="donateDiv"><a id="donate">打赏</a></div>
<div class="post-footer" id="post-footer">
    <div class="post-info">
        <div class="post-info-line">
            <div class="post-info-mod">
                <span>更新于 2020-12-11</span>
            </div>
            <div class="post-info-license"></div>
        </div>
        <div class="post-info-line">
            <div class="post-info-md"></div>
            <div class="post-info-share">
                <span></span>
            </div>
        </div>
    </div>

    <div class="post-info-more">
        <section class="post-tags"><i class="fas fa-tags fa-fw"></i>&nbsp;<a href="/tags/spring%E6%BA%90%E7%A0%81/">spring源码</a>,&nbsp;<a href="/tags/spring%E9%97%AE%E9%A2%98/">spring问题</a></section>
        <section>
            <span><a href="javascript:void(0);" onclick="window.history.back();">返回</a></span>&nbsp;|&nbsp;<span><a href="/">主页</a></span>
        </section>
    </div>

    <div class="post-nav"><a href="/posts/spring/21-load-servlet-container-initializer-on-startup/" class="prev" rel="prev" title="Spring源码 - web容器启动时ServletContainerInitializer的加载"><i class="fas fa-angle-left fa-fw"></i>Spring源码 - web容器启动时ServletContainerInitializer的加载</a>
            <a href="/posts/spring/22-enable-web-mvc-main-embedded-tomcat/" class="next" rel="next" title="Spring源码 - MVC的支持入口及嵌入式Tomcat的使用">Spring源码 - MVC的支持入口及嵌入式Tomcat的使用<i class="fas fa-angle-right fa-fw"></i></a></div>
</div>
<div id="comments"><div id="valine" class="comment"></div><noscript>
                Please enable JavaScript to view the comments powered by <a href="https://valine.js.org/">Valine</a>.
            </noscript></div></article></div>
            </main><footer class="footer">
        <div class="footer-container"><div class="footer-line">由 <a href="https://gohugo.io/" target="_blank" rel="noopener noreffer" title="Hugo 0.102.3">Hugo</a> 强力驱动 | 主题 - <a href="https://github.com/dillonzq/LoveIt" target="_blank" rel="noopener noreffer" title="LoveIt 0.2.10"><i class="far fa-kiss-wink-heart fa-fw"></i> LoveIt</a>
                </div><div class="footer-line"><i class="far fa-copyright fa-fw"></i><span itemprop="copyrightYear">2020 - 2024</span><span class="author" itemprop="copyrightHolder">&nbsp;<a href="https://wlizhi.cc" target="_blank">Wlizhi</a></span><span class="icp-splitter">&nbsp;|&nbsp;</span><br class="icp-br"/>
                    <span class="icp"><a href='https://beian.miit.gov.cn/' target='_blank'>豫ICP备17048163号<a/></span></div>
        </div>
    </footer></div>

        <div id="fixed-buttons"><a href="#" id="back-to-top" class="fixed-button" title="回到顶部">
                <i class="fas fa-arrow-up fa-fw"></i>
            </a><a href="#" id="view-comments" class="fixed-button" title="查看评论">
                <i class="fas fa-comment fa-fw"></i>
            </a>
        </div><link rel="stylesheet" href="/lib/valine/valine.min.css"><link rel="stylesheet" href="/lib/lightgallery/lightgallery.min.css"><script type="text/javascript" src="/lib/valine/Valine.min.js"></script><script type="text/javascript" src="/lib/smooth-scroll/smooth-scroll.min.js"></script><script type="text/javascript" src="/lib/autocomplete/autocomplete.min.js"></script><script type="text/javascript" src="/lib/algoliasearch/algoliasearch-lite.umd.min.js"></script><script type="text/javascript" src="/lib/lazysizes/lazysizes.min.js"></script><script type="text/javascript" src="/lib/lightgallery/lightgallery.min.js"></script><script type="text/javascript" src="/lib/lightgallery/lg-thumbnail.min.js"></script><script type="text/javascript" src="/lib/lightgallery/lg-zoom.min.js"></script><script type="text/javascript" src="/lib/clipboard/clipboard.min.js"></script><script type="text/javascript">window.config={"code":{"copyTitle":"复制到剪贴板","maxShownLines":35},"comment":{"valine":{"appId":"4yIHB0Rs1r3ykDVxayI5nqj3-gzGzoHsz","appKey":"ALr4H1hlK94girLDEUCGmp3o","avatar":"mp","el":"#valine","emojiCDN":"https://cdn.jsdelivr.net/npm/emoji-datasource-google@5.0.1/img/google/64/","emojiMaps":{"100":"1f4af.png","alien":"1f47d.png","anger":"1f4a2.png","angry":"1f620.png","anguished":"1f627.png","astonished":"1f632.png","black_heart":"1f5a4.png","blue_heart":"1f499.png","blush":"1f60a.png","bomb":"1f4a3.png","boom":"1f4a5.png","broken_heart":"1f494.png","brown_heart":"1f90e.png","clown_face":"1f921.png","cold_face":"1f976.png","cold_sweat":"1f630.png","confounded":"1f616.png","confused":"1f615.png","cry":"1f622.png","crying_cat_face":"1f63f.png","cupid":"1f498.png","dash":"1f4a8.png","disappointed":"1f61e.png","disappointed_relieved":"1f625.png","dizzy":"1f4ab.png","dizzy_face":"1f635.png","drooling_face":"1f924.png","exploding_head":"1f92f.png","expressionless":"1f611.png","face_vomiting":"1f92e.png","face_with_cowboy_hat":"1f920.png","face_with_hand_over_mouth":"1f92d.png","face_with_head_bandage":"1f915.png","face_with_monocle":"1f9d0.png","face_with_raised_eyebrow":"1f928.png","face_with_rolling_eyes":"1f644.png","face_with_symbols_on_mouth":"1f92c.png","face_with_thermometer":"1f912.png","fearful":"1f628.png","flushed":"1f633.png","frowning":"1f626.png","ghost":"1f47b.png","gift_heart":"1f49d.png","green_heart":"1f49a.png","grimacing":"1f62c.png","grin":"1f601.png","grinning":"1f600.png","hankey":"1f4a9.png","hear_no_evil":"1f649.png","heart":"2764-fe0f.png","heart_decoration":"1f49f.png","heart_eyes":"1f60d.png","heart_eyes_cat":"1f63b.png","heartbeat":"1f493.png","heartpulse":"1f497.png","heavy_heart_exclamation_mark_ornament":"2763-fe0f.png","hole":"1f573-fe0f.png","hot_face":"1f975.png","hugging_face":"1f917.png","hushed":"1f62f.png","imp":"1f47f.png","innocent":"1f607.png","japanese_goblin":"1f47a.png","japanese_ogre":"1f479.png","joy":"1f602.png","joy_cat":"1f639.png","kiss":"1f48b.png","kissing":"1f617.png","kissing_cat":"1f63d.png","kissing_closed_eyes":"1f61a.png","kissing_heart":"1f618.png","kissing_smiling_eyes":"1f619.png","laughing":"1f606.png","left_speech_bubble":"1f5e8-fe0f.png","love_letter":"1f48c.png","lying_face":"1f925.png","mask":"1f637.png","money_mouth_face":"1f911.png","nauseated_face":"1f922.png","nerd_face":"1f913.png","neutral_face":"1f610.png","no_mouth":"1f636.png","open_mouth":"1f62e.png","orange_heart":"1f9e1.png","partying_face":"1f973.png","pensive":"1f614.png","persevere":"1f623.png","pleading_face":"1f97a.png","pouting_cat":"1f63e.png","purple_heart":"1f49c.png","rage":"1f621.png","relaxed":"263a-fe0f.png","relieved":"1f60c.png","revolving_hearts":"1f49e.png","right_anger_bubble":"1f5ef-fe0f.png","robot_face":"1f916.png","rolling_on_the_floor_laughing":"1f923.png","scream":"1f631.png","scream_cat":"1f640.png","see_no_evil":"1f648.png","shushing_face":"1f92b.png","skull":"1f480.png","skull_and_crossbones":"2620-fe0f.png","sleeping":"1f634.png","sleepy":"1f62a.png","slightly_frowning_face":"1f641.png","slightly_smiling_face":"1f642.png","smile":"1f604.png","smile_cat":"1f638.png","smiley":"1f603.png","smiley_cat":"1f63a.png","smiling_face_with_3_hearts":"1f970.png","smiling_imp":"1f608.png","smirk":"1f60f.png","smirk_cat":"1f63c.png","sneezing_face":"1f927.png","sob":"1f62d.png","space_invader":"1f47e.png","sparkling_heart":"1f496.png","speak_no_evil":"1f64a.png","speech_balloon":"1f4ac.png","star-struck":"1f929.png","stuck_out_tongue":"1f61b.png","stuck_out_tongue_closed_eyes":"1f61d.png","stuck_out_tongue_winking_eye":"1f61c.png","sunglasses":"1f60e.png","sweat":"1f613.png","sweat_drops":"1f4a6.png","sweat_smile":"1f605.png","thinking_face":"1f914.png","thought_balloon":"1f4ad.png","tired_face":"1f62b.png","triumph":"1f624.png","two_hearts":"1f495.png","unamused":"1f612.png","upside_down_face":"1f643.png","weary":"1f629.png","white_frowning_face":"2639-fe0f.png","white_heart":"1f90d.png","wink":"1f609.png","woozy_face":"1f974.png","worried":"1f61f.png","yawning_face":"1f971.png","yellow_heart":"1f49b.png","yum":"1f60b.png","zany_face":"1f92a.png","zipper_mouth_face":"1f910.png","zzz":"1f4a4.png"},"enableQQ":true,"highlight":true,"lang":"zh-cn","meta":["nick","mail","link"],"pageSize":5,"placeholder":"昵称栏输入QQ，会使用QQ昵称和头像、并自动补充QQ邮箱到邮箱栏。\r\n正确填写邮箱更容易及时得到回复。\r\n说点什么吧...","recordIP":true,"visitor":true}},"lightGallery":{"actualSize":false,"exThumbImage":"data-thumbnail","hideBarsDelay":2000,"selector":".lightgallery","speed":400,"thumbContHeight":80,"thumbWidth":80,"thumbnail":true},"search":{"algoliaAppID":"1U459KF21F","algoliaIndex":"LoveItSite","algoliaSearchKey":"0433ffe95d71201a4f7c3e04b0125ac5","highlightTag":"em","maxResultLength":10,"noResultsFound":"没有找到结果","snippetLength":50,"type":"algolia"}};</script><script type="text/javascript" src="/js/theme.min.js"></script><script type="text/javascript" src="/js/donate.js"></script></body>
</html>
